package com.lolan.training.libreoffice.services;

import com.lolan.training.common.constants.ErrorCode;
import com.lolan.training.libreoffice.constants.FileExtension;
import org.apache.poi.hssf.usermodel.HSSFPrintSetup;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFPrintSetup;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.jodconverter.core.DocumentConverter;
import org.jodconverter.core.document.DefaultDocumentFormatRegistry;
import org.jodconverter.core.document.DocumentFormat;
import org.jodconverter.core.office.OfficeException;
import org.jodconverter.core.office.OfficeManager;
import org.jodconverter.local.LocalConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;

@Component
public class LibreOfficeService {

	@Autowired
	OfficeManager officeManager;

	private void disableComments(Sheet sheet) {
		if (sheet instanceof XSSFSheet || sheet instanceof HSSFSheet) {
			Iterator<Row> rowIterator = sheet.iterator();
			while (rowIterator.hasNext()) {
				Row row = rowIterator.next();
				Iterator<Cell> cellIterator = row.iterator();
				while (cellIterator.hasNext()) {
					Cell cell = cellIterator.next();
					CellStyle cellStyle = cell.getCellStyle();
					cellStyle.setWrapText(true);
					cell.setCellStyle(cellStyle);
					Comment comment = cell.getCellComment();
					if (comment != null) {
						System.out.println("Comment :- " + comment.getString());
						cell.removeCellComment();

					}
				}
			}
		}
	}
	private HashMap<String, Object> getStoreProperties() {
		HashMap<String, Object> loadProperties = new HashMap<>();
		loadProperties.put("FilterData", getFilterData());
		return loadProperties;
	}

	private HashMap<String, Object> getFilterData() {
		HashMap<String, Object> filterData = new HashMap<>();
		filterData.put("IsSkipEmptyPages", new Boolean(true));
		filterData.put("SelectPdfVersion", new Integer(0));
		return filterData;
	}
	public InputStream getExcelStream(String sourceExt, InputStream inputStream, ByteArrayOutputStream bos) throws Exception {
		// stream re-order to fit the all content
		if(sourceExt.contains(FileExtension.XLS.getExt())) {
			XSSFWorkbook xssfWorkbook = (XSSFWorkbook) WorkbookFactory.create(inputStream);
			Iterator<Sheet> iterator = xssfWorkbook.sheetIterator();
			while (iterator.hasNext()) {
				XSSFSheet xssfSheet = (XSSFSheet) iterator.next();
				disableComments(xssfSheet);
				xssfSheet.setFitToPage(true);
				xssfSheet.setAutobreaks(true);
				XSSFPrintSetup printSetup = xssfSheet.getPrintSetup();
				printSetup.setFitWidth((short) 1);
				printSetup.setFitHeight((short) 0);
			}
			xssfWorkbook.write(bos);
			inputStream = new ByteArrayInputStream(bos.toByteArray());
			xssfWorkbook.close();
		} else {
			HSSFWorkbook xlsWorkbook = (HSSFWorkbook) WorkbookFactory.create(inputStream);
			Iterator<Sheet> iterator = xlsWorkbook.sheetIterator();
			while (iterator.hasNext()) {
				HSSFSheet hssfSheet =  (HSSFSheet) iterator.next();
				disableComments(hssfSheet);
				hssfSheet.setFitToPage(true);
				hssfSheet.setAutobreaks(true);
				HSSFPrintSetup hssfPrintSetup = hssfSheet.getPrintSetup();
				hssfPrintSetup.setFitWidth((short) 1);
				hssfPrintSetup.setFitHeight((short) 0);
			}
			xlsWorkbook.write(bos);
			inputStream = new ByteArrayInputStream(bos.toByteArray());
			xlsWorkbook.close();
		}
		return inputStream;
	}

	public void doConvert(InputStream inputStream, DocumentFormat targetFormat, String sourceExt, ByteArrayOutputStream baos) throws Exception {
		// xls file handling
		if(sourceExt.contains(FileExtension.XLS.getExt()) || sourceExt.contains(FileExtension.XLSX.getExt())) {
			inputStream = this.getExcelStream(sourceExt, inputStream, new ByteArrayOutputStream());
			// hwp file handling
		}
//		else if(sourceExt.contains(ScraperConstant.HWP_EXTENSION)) {
//			// looking for hwp file handling
//		}
		final DocumentConverter loConverter = LocalConverter.builder().officeManager(officeManager).storeProperties(getStoreProperties()).build();
		loConverter.convert(inputStream).to(baos).as(targetFormat).execute();
	}

	public void doConvertOfficial(final DocumentFormat targetFormat, final MultipartFile inputFile, ByteArrayOutputStream baos) {
		try {
			LocalConverter.builder().officeManager(officeManager).build()
				.convert(inputFile.getInputStream())
				.to(baos)
				.as(targetFormat)
				.execute();
		} catch (OfficeException | IOException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}


}

